package com.learn.beatbox

import android.content.res.AssetFileDescriptor
import android.content.res.AssetManager
import android.media.SoundPool
import android.util.Log

private const val TAG = "BeatBox"

private const val SOUNDS_FOLDER = "sample_sounds"

private const val MAX_SOUNDS = 5

class BeatBox(private val assets: AssetManager) {

    val sounds: List<Sound>

    // SoundPool.Builder可以创建一个SoundPool实例。setMaxStreams(Int)选项可以指定某个时刻同时播放多少个音频。
    // 这里指定了五个。已经播放了五个音频时，如果再尝试播放第6个，SoundPool则会停止播放最早播放的那个音频。
    private val soundPool = SoundPool.Builder()
        .setMaxStreams(MAX_SOUNDS)
        .build()

    init {
        sounds = loadSounds()
    }

    fun play(sound: Sound) {
        sound.soundId?.let {
            // 这些参数依次是：音频ID、左音量、右音量、优先级（无效）、是否循环和播放速率。
            // 我们需要最大音量和常速播放，所以传入值1.0。是否循环参数传入0，代表不循环。（如果想无限循环，可以传入-1。
            soundPool.play(it, 1f, 1f, 1, 0, 1f)
        }
    }

    fun release() {
        soundPool.release()
    }

    private fun loadSounds(): List<Sound> {
        val soundNames: Array<String>
        try {
            soundNames = assets.list(SOUNDS_FOLDER)!!
            Log.d(TAG, "Found ${soundNames.size} sounds")
        } catch (e: Exception) {
            Log.e(TAG, "Could not list assets. Directory: $SOUNDS_FOLDER", e)
            return emptyList()
        }

        val sounds = mutableListOf<Sound>()
        soundNames.forEach { filename ->
            val assetPath = "$SOUNDS_FOLDER/$filename"
            val sound = Sound(assetPath)

            try {
                load(sound)
                sounds.add(sound)
            } catch (e: Exception) {
                Log.e(TAG, "Could not load sound $filename", e)
            }
        }
        return sounds
    }

    private fun load(sound: Sound) {
        val afd: AssetFileDescriptor = assets.openFd(sound.assetPath)
        val soundId = soundPool.load(afd, 1)
        sound.soundId = soundId
    }
}